import string
import sys

def strip_unprintable(input_string):
    try:
        filter_unprintable = strip_unprintable.filter
    except AttributeError: # only the first time it is called
        allchars = string.maketrans('','')
        delchars = allchars.translate(allchars, string.printable)
        filter_unprintable = strip_unprintable.filter = lambda input: input.translate(allchars,
delchars)
    return filter_unprintable(input_string)

def bin(a):
    s=''
    t={'0':'000','1':'001','2':'010','3':'011',
       '4':'100','5':'101','6':'110','7':'111'}
    for c in oct(a)[1:]:
        s+=t[c]
    return s
    
def rle_encode(unrle_data):
    rle_data = []

    last_sample = None
    rl_counter = 0
    
    for sample in unrle_data:
        if last_sample != None:
            if last_sample == sample:
                # increment counter
                rl_counter += 1
            else:
                # found something different
                rle_data.append(rl_counter)
                rle_data.append(last_sample)
                last_sample = sample
                rl_counter = 1
        else:
            last_sample = sample
            rl_counter = 1
    
    if rl_counter > 0:
        rle_data.append(rl_counter)
        rle_data.append(last_sample)
                    
    return rle_data

# weird rle_decode.... but it's like this in winarena
def rle_decode(rle_data, stop_count = None):
    if not stop_count:
        stop = len(rle_data)
    else:
        stop = stop_count
    i = 0
    o = 0
    
    unrle_data = []
    
    while o < stop and i < stop:
        sample = rle_data[i]
        i += 1

        # compressed packet
        if sample & 0x80:
            try:
                value = rle_data[i]
            except IndexError:
                print 'IndexError: i ', i, ' value: ', value, 'len rle_data: ', len(rle_data)
                sys.exit(1)
            i += 1
            count = sample - 0x7F
            
            for idx in xrange(count):
                unrle_data.append(value)
                o += 1
            #print 'o: ', o
        else:
            count = sample + 1
  
            for idx in xrange(count):
                unrle_data.append(rle_data[i])
                i += 1
                o += 1
            #print 'o2: ', o
        
        #print 'i: ', i
    return unrle_data, i

#===============================================================================
#     Demux7() ... Demux1()
# 
#     What follow are a series of demuxing routines used by CFA files.  Image
#     data in CFAs assignes a unique index to each color used, then packed into
#     fewer bits.  For example, if there are only 16 unique colors, each of
#     those colors can be packed into 4-bit values, with two pixels packed into
#     one byte.
# 
#     These routines take a packed sequence of bytes, and unpack them into
#     2 or more 8-bit values to make them easier to read.  The caller will still
#     need to dereference the resulting values to convert them into meaningful
#     color palette indices.
#===============================================================================

def Demux7(pIn):
    pOut = [0 for i in xrange(8)]
    
    pOut[0] = ((pIn[0] & 0xFE) >> 1)
    pOut[1] = ((pIn[0] & 0x01) << 6) | ((pIn[1] & 0xFC) >> 2)
    pOut[2] = ((pIn[1] & 0x03) << 5) | ((pIn[2] & 0xF8) >> 3)
    pOut[3] = ((pIn[2] & 0x07) << 4) | ((pIn[3] & 0xF0) >> 4)
    pOut[4] = ((pIn[3] & 0x0F) << 3) | ((pIn[4] & 0xE0) >> 5)
    pOut[5] = ((pIn[4] & 0x1F) << 2) | ((pIn[5] & 0xC0) >> 6)
    pOut[6] = ((pIn[5] & 0x3F) << 1) | ((pIn[6] & 0x80) >> 7)
    pOut[7] = ((pIn[6] & 0x7F)     )
    
    return pOut

#===============================================================================
#     Demux6()
# 
#     Decodes 6-bit compressed data.  In this format, four 6-bit pixels are
#     packed into three bytes.  Assumes that pIn points to 3 bytes, which are
#     then unpacked and the resulting 4 bytes written to pOut.
# 
#     If the input contains less than 3 bytes of valid data, the pointer still
#     still needs to reference a 3-byte sequence, but the missing high bytes
#     should be padded with zeroes to permit all output values to be decoded
#     correctly.
#===============================================================================
def Demux6(pIn):
    pOut = [0 for i in xrange(4)]
    
    pOut[0] = ((pIn[0] & 0xFC) >> 2)
    pOut[1] = ((pIn[0] & 0x03) << 4) | ((pIn[1] & 0xF0) >> 4)
    pOut[2] = ((pIn[1] & 0x0F) << 2) | ((pIn[2] & 0xC0) >> 6)
    pOut[3] = ((pIn[2] & 0x3F)     )
    
    return pOut

#===============================================================================
#     Demux5()
# 
#     This is the 5-bit version of Demux...().  In this format, eight 5-bit
#     values are packed into 5 bytes.  The bits need to be reshuffled and
#     stored in the 8 bytes that pOut points to.
#===============================================================================

def Demux5(pIn):
    pOut = [0 for i in xrange(8)]
    
    pOut[0] = ((pIn[0] & 0xF8) >> 3)
    pOut[1] = ((pIn[0] & 0x07) << 2) | ((pIn[1] & 0xC0) >> 6)
    pOut[2] = ((pIn[1] & 0x3E) >> 1)
    pOut[3] = ((pIn[1] & 0x01) << 4) | ((pIn[2] & 0xF0) >> 4)
    pOut[4] = ((pIn[2] & 0x0F) << 1) | ((pIn[3] & 0x80) >> 7)
    pOut[5] = ((pIn[3] & 0x7C) >> 2)
    pOut[6] = ((pIn[3] & 0x03) << 3) | ((pIn[4] & 0xE0) >> 5)
    pOut[7] = ((pIn[4] & 0x1F)     )
    
    return pOut

#===============================================================================
#     Demux4()
#===============================================================================

def Demux4(pIn):
    pOut = [0 for i in xrange(4)]
    
    pOut[0] = (pIn[0] & 0xF0) >> 4
    pOut[1] = (pIn[0] & 0x0F)
    pOut[2] = (pIn[1] & 0xF0) >> 4
    pOut[3] = (pIn[1] & 0x0F)
    
    return pOut

#===============================================================================
#     Demux3()
#===============================================================================

def Demux3(pIn):
    pOut = [0 for i in xrange(8)]
    
    pOut[0] = ((pIn[0] & 0xE0) >> 5)
    pOut[1] = ((pIn[0] & 0x1C) >> 2)
    pOut[2] = ((pIn[0] & 0x03) << 1) | ((pIn[1] & 0x80) >> 7)
    pOut[3] = ((pIn[1] & 0x70) >> 4)
    pOut[4] = ((pIn[1] & 0x0E) >> 1)
    pOut[5] = ((pIn[1] & 0x01) << 2) | ((pIn[2] & 0xC0) >> 6)
    pOut[6] = ((pIn[2] & 0x38) >> 3)
    pOut[7] = ((pIn[2] & 0x07)     )
    
    return pOut

#===============================================================================
#     Demux2()
#===============================================================================

def Demux2(pIn):
    pOut = [0 for i in xrange(4)]
    
    pOut[0] = ((pIn[0] & 0xC0) >> 6)
    pOut[1] = ((pIn[0] & 0x30) >> 4)
    pOut[2] = ((pIn[0] & 0x0C) >> 2)
    pOut[3] = ((pIn[0] & 0x03)     )
    
    return pOut


#===============================================================================
#     Demux1()
#===============================================================================

def Demux1(pIn):
    pOut = [0 for i in xrange(8)]
    
    pOut[0] = ((pIn[0] & 0x80) >> 7)
    pOut[1] = ((pIn[0] & 0x40) >> 6)
    pOut[2] = ((pIn[0] & 0x20) >> 5)
    pOut[3] = ((pIn[0] & 0x10) >> 4)
    pOut[4] = ((pIn[0] & 0x08) >> 3)
    pOut[5] = ((pIn[0] & 0x04) >> 2)
    pOut[6] = ((pIn[0] & 0x02) >> 1)
    pOut[7] = ((pIn[0] & 0x01)     )

    return pOut